import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { supermapReady } from '/@packages/components'
import { ElMessage } from 'element-plus'
import { getGradientColors } from '/@src/utils'

export default function () {
  const { $myapp } = supermapReady()
  // 点云图层名字
  const pointLayerName = '点云'
  // 初始设置点云特征值原始数据
  const srcOptions = [
    {
      value: 'PointCloudClassCode',
      label: '类别值'
    },
    {
      value: 'PointCloudIntensity',
      label: '强度值'
    },
    {
      value: 'VertexWeight',
      label: '高度值'
    }
  ]
  // 初始设置特征值代表的意思，及默认颜色
  const classificTypes = [
    {
      value: 2,
      label: '地面',
      defaultColor: 'rgb(232,173,10)'
    },
    {
      value: 5,
      label: '植被',
      defaultColor: 'rgb(0,255,0)'
    },
    {
      value: 7,
      label: '其他',
      defaultColor: 'rgb(0,0,255)'
    },
    {
      value: 17,
      label: '电缆',
      defaultColor: 'rgb(0,255,255)'
    },
    {
      value: 18,
      label: '电塔',
      defaultColor: 'rgb(255,0,0)'
    }
  ]
  // 点云图层
  let pointLayer = null

  onMounted(() => {
    init()
  })
  onBeforeUnmount(() => {
    if (pointLayer) {
      var hyp = new SuperMap3D.HypsometricSetting()
      hyp.MaxVisibleValue = -1000

      pointLayer.hypsometricSetting = {
        hypsometricSetting: hyp,
        analysisMode:
          SuperMap3D.HypsometricSettingEnum.AnalysisRegionMode.ARM_NONE
      }
    }
  })
  // 初始化，查找点云图层
  const init = async () => {
    pointLayer = $myapp.viewer.scene.layers.find(pointLayerName)
    if (pointLayer) {
      $myapp.viewer.zoomTo(pointLayer)
      layerClassifics.value = []
      layerHeightExtremum.value = []
      layerIntensityExtremum.value = []
      // 获取所有类别值
      const fieldVals = await pointLayer.getAllFieldValues(
        SuperMap3D.S3MFieldType.PointCloudClassification
      )
      fieldVals.forEach((item) => {
        const source = classificTypes.find((ct) => ct.value === item.id)
        if (source) {
          layerClassifics.value.push(source)
        }
      })
      layerClassifics.value.sort((a, b) => a.value - b.value)
      // 根据高度获取极值
      const heightExtremum = getExtremumByType(pointLayer, 'VertexWeight')
      if (heightExtremum) {
        layerHeightExtremum.value.push({
          label: '最低值：' + heightExtremum.minValue,
          value: heightExtremum.minValue,
          color: '#0000ff'
        })
        layerHeightExtremum.value.push({
          label: '最高值：' + heightExtremum.maxValue,
          value: heightExtremum.maxValue,
          color: '#ff0000'
        })
      }
      // 根据强度获取极值
      const intensityExtremum = getExtremumByType(
        pointLayer,
        'PointCloudIntensity'
      )
      if (intensityExtremum) {
        layerIntensityExtremum.value.push({
          label: '最小值：' + intensityExtremum.minValue,
          value: intensityExtremum.minValue,
          color: '#0000ff'
        })
        layerIntensityExtremum.value.push({
          label: '最大值：' + intensityExtremum.maxValue,
          value: intensityExtremum.maxValue,
          color: '#ff0000'
        })
      }

      // 获取特征字段选项
      const temporaInfos = pointLayer.temporaInfos
      selectFieldOptions.value = []
      Object.keys(temporaInfos).forEach((key) => {
        selectFieldOptions.value.push(srcOptions.find((so) => so.value === key))
      })
      if (selectFieldOptions.value.length > 0) {
        selectField.value = 'PointCloudClassCode'
      }
    } else {
      ElMessage.error('点云图层为空，请确定是否有点云图层')
    }
  }
  // 选择显示的类型
  const selectField = ref('')
  // 设置可选择哪些类型
  const selectFieldOptions = ref([])

  // 点云图层有哪些特征值
  const layerClassifics = ref([])
  // 点云图层的高度极值
  const layerHeightExtremum = ref([])
  // 点云图层的强度极值
  const layerIntensityExtremum = ref([])

  // 根据传入的颜色表设置当前S3M图层的分层设色
  const setLayerHypByColorTable = (s3mLayer, colorTable, fieldName) => {
    let hyp = new SuperMap3D.HypsometricSetting()
    hyp.DisplayMode = SuperMap3D.HypsometricSettingEnum.DisplayMode.FACE
    hyp.ColorTable = colorTable
    s3mLayer.setHypsometricSetting(hyp, {
      fieldName: fieldName
    })
  }
  // 根据特征值获取图层的极值
  const getExtremumByType = (s3mLayer, fielNam) => {
    let categoryInfos = s3mLayer.temporaInfos
    let categoryFieldInfo = categoryInfos[fielNam]
    if (!categoryFieldInfo) {
      return undefined
    }
    let minValue = categoryFieldInfo.min[0]
    let maxValue = categoryFieldInfo.max[0]
    return { minValue, maxValue }
  }
  // 按照类别值创建颜色表
  const createClassificColorTable = (s3mLayer) => {
    const { minValue, maxValue } = getExtremumByType(
      s3mLayer,
      'PointCloudClassCode'
    )
    const colorTable_classCode = new SuperMap3D.ColorTable()
    if (minValue < layerClassifics.value[0].value) {
      colorTable_classCode.insert(
        minValue,
        SuperMap3D.Color.fromCssColorString('rgb(0,0,0)')
      )
    }
    layerClassifics.value.forEach((item) => {
      colorTable_classCode.insert(
        item.value,
        SuperMap3D.Color.fromCssColorString(item.defaultColor)
      )
    })
    if (
      maxValue > layerClassifics.value[layerClassifics.value.length - 1].value
    ) {
      colorTable_classCode.insert(
        maxValue,
        SuperMap3D.Color.fromCssColorString('rgb(255,255,255)')
      )
    }
    return colorTable_classCode
  }
  // 根据高度极值创建颜色表
  const createHeightColorTable = (s3mLayer) => {
    const { minValue, maxValue } = getExtremumByType(s3mLayer, 'VertexWeight')
    const dValue = (maxValue - minValue) / 10
    const colorTable_Elv = new SuperMap3D.ColorTable()
    const minColor = layerHeightExtremum.value[0].color
    const maxColor = layerHeightExtremum.value[1].color
    const colors = getGradientColors(minColor, maxColor, 12)
    colors.forEach((color, index) => {
      colorTable_Elv.insert(
        minValue + dValue * index,
        SuperMap3D.Color.fromCssColorString(color)
      )
    })
    return colorTable_Elv
  }
  // 根据强度极值构建颜色表
  const createIntensityColorTable = (s3mLayer) => {
    const { minValue, maxValue } = getExtremumByType(
      s3mLayer,
      'PointCloudIntensity'
    )
    const dValue = (maxValue - minValue) / 10
    const colorTable_Int = new SuperMap3D.ColorTable()
    const minColor = layerIntensityExtremum.value[0].color
    const maxColor = layerIntensityExtremum.value[1].color
    const colors = getGradientColors(minColor, maxColor, 12)
    colors.forEach((color, index) => {
      colorTable_Int.insert(
        minValue + dValue * index,
        SuperMap3D.Color.fromCssColorString(color)
      )
    })
    return colorTable_Int
  }
  // 选择显示类型改变事件
  const onSelectChange = () => {
    switch (selectField.value) {
      case 'PointCloudClassCode':
        showClassific()
        break
      case 'PointCloudIntensity':
        showIntensity()
        break
      case 'VertexWeight':
        showHeight()
        break
    }
  }
  // 按类别显示
  const showClassific = () => {
    const colorTable1 = createClassificColorTable(pointLayer)
    setLayerHypByColorTable(pointLayer, colorTable1, 'PointCloudClassCode')
  }
  // 按高度显示
  const showHeight = () => {
    const colorTable3 = createHeightColorTable(pointLayer)
    setLayerHypByColorTable(pointLayer, colorTable3, 'VertexWeight')
  }
  // 按强度显示
  const showIntensity = () => {
    const colorTable2 = createIntensityColorTable(pointLayer)
    setLayerHypByColorTable(pointLayer, colorTable2, 'PointCloudIntensity')
  }

  // 监测类别值颜色参数改变事件，更新显示效果
  watch(
    () => layerClassifics,
    () => {
      if (selectField.value === 'PointCloudClassCode') {
        showClassific()
      }
    },
    {
      deep: true
    }
  )
  // 监测高度值颜色参数改变事件，更新显示效果
  watch(
    () => layerHeightExtremum,
    () => {
      if (selectField.value === 'VertexWeight') {
        showHeight()
      }
    },
    {
      deep: true
    }
  )
  // 监测强度值颜色参数改变事件，更新显示效果
  watch(
    () => layerIntensityExtremum,
    () => {
      if (selectField.value === 'PointCloudIntensity') {
        showIntensity()
      }
    },
    {
      deep: true
    }
  )
  return {
    selectField,
    selectFieldOptions,
    layerClassifics,
    layerHeightExtremum,
    layerIntensityExtremum,
    onSelectChange
  }
}
